package com.demo.util.excel.builders;


import com.demo.util.CollUtil;
import com.demo.util.equals.functional.Equals;
import com.demo.util.excel.beans.ExcelColumnVO;
import com.demo.util.excel.enums.ExcelDataType;
import com.demo.util.excel.functional.ExcelColumnHandle;
import com.demo.util.excel.utils.LambdaExcelColumnUtil;
import com.demo.util.lambda.beans.SFunction;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;

public class ExcelColumnsBuilder<T> {

    private final List<ExcelColumnVO<T>> columns = new ArrayList<>();

    public List<ExcelColumnVO<T>> done(){ return columns; }

    public ExcelColumnsBuilder<T> add(String title) {
        columns.add(new ExcelColumnVO<T>() {{
            setTitle(title);
        }});
        return this;
    }

    public ExcelColumnsBuilder<T> add(String title, String field) {
        columns.add(new ExcelColumnVO<T>(){{
            setTitle(title);
            setField(field);
        }});
        return this;
    }

    public ExcelColumnsBuilder<T> add(ExcelColumnVO<T> column) {
        columns.add(column);
        return this;
    }

    public <TF>  ExcelColumnsBuilder<T> add(SFunction<TF, ?> func) {
        columns.add(LambdaExcelColumnUtil.getFuncColumn(func));
        return this;
    }

    public ExcelColumnsBuilder<T> addAll(ExcelColumnsBuilder<T> addColumns) {
        return addAll(addColumns.done());
    }

    public ExcelColumnsBuilder<T> addAll(Collection<ExcelColumnVO<T>> addColumns) {
        columns.addAll(addColumns);
        return this;
    }

    public <TF> ExcelColumnsBuilder<T> addAll(Class<TF> clazz) {
        columns.addAll(LambdaExcelColumnUtil.getClassAllColumns(clazz));
        return this;
    }

    private ExcelColumnsBuilder<T> setColumnInfo(ExcelColumnHandle<T> setColumnInfoFunc) {
        ExcelColumnVO<T> column = CollUtil.getLast(columns);
        if (column == null) {
            return this;
        }
        setColumnInfoFunc.handle(column);
        return this;
    }

    public ExcelColumnsBuilder<T> setMerge(Equals<T> merge) {
        return setColumnInfo(column -> {
            column.setMerge(merge);
        });
    }

    public ExcelColumnsBuilder<T> setHeaderStyle(String name) {
        return setHeaderStyle(column -> name);
    }

    public ExcelColumnsBuilder<T> setHeaderStyle(Function<ExcelColumnVO<T>, String> headerStyle) {
        return setColumnInfo(column -> {
            column.setHeaderStyle(headerStyle);
        });
    }

    public ExcelColumnsBuilder<T> setCellStyle(String name) {
        return setCellStyle(data -> name);
    }

    public ExcelColumnsBuilder<T> setCellStyle(Function<T, String> cellStyle) {
        return setColumnInfo(column -> {
            column.setCellStyle(cellStyle);
        });
    }

    public ExcelColumnsBuilder<T> setDataType(ExcelDataType dataType) {
        return setColumnInfo(column -> {
            column.setDataType(dataType);
        });
    }

    public ExcelColumnsBuilder<T> setChildren(ExcelColumnsBuilder<T> children) {
        return setChildren(children.done());
    }

    public <TF> ExcelColumnsBuilder<T> setChildren(Class<TF> clazz) {
        return setChildren(LambdaExcelColumnUtil.getClassAllColumns(clazz));
    }

    public ExcelColumnsBuilder<T> setChildren(List<ExcelColumnVO<T>> children) {
        return setColumnInfo(column -> {
            column.setChildren(children);
        });
    }

}